#ifndef QUAD_TREE_OCCUPANT_HPP
#define QUAD_TREE_OCCUPANT_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SmegTools/Config.h>
#include <SmegCore/Math/BoundingVolumes/AABB.hpp>
#include <SmegCore/Entity/BaseObject.hpp>

#include <SmegTools/Debug/DebugNew.hpp>

namespace smeg {
    namespace light {

class QuadTreeNode;
class QuadTree;

////////////////////////////////////////////////////////////
/// Represents an occupant of a QuadTree
////////////////////////////////////////////////////////////
class QuadTreeOccupant : public core::BaseObject
{
public:
    enum eType_Occupant {
        eType_Static    = 0,
        eType_NonStatic = 1,
        eType_All       = 2
    };
    
    ////////////////////////////////////////////////////////////
    /// Default Constructor
    ///
    /// \param _Center :    Center of the occupant
    /// \param _fAngleDeg : Rotation in degree of the occupant
    /// \param _bIsStatic : Whether the occupant is static or not
    ///
    ////////////////////////////////////////////////////////////
                        QuadTreeOccupant();
    ////////////////////////////////////////////////////////////
    /// Copy Constructor
    ///
    /// \param _Copy :      Occupant to copy from
    ///
    ////////////////////////////////////////////////////////////
                        QuadTreeOccupant( const QuadTreeOccupant& _Copy );
    ////////////////////////////////////////////////////////////
    /// Destructor
    ///
    ////////////////////////////////////////////////////////////
    virtual             ~QuadTreeOccupant();
    
    ////////////////////////////////////////////////////////////
    /// If we are in a tree, call its update
    ///
    ////////////////////////////////////////////////////////////
    void                TreeUpdate();

    ////////////////////////////////////////////////////////////
    /// Remove this occupant from the tree
    ///
    ////////////////////////////////////////////////////////////
    void                RemoveFromTree();
    
    /*********************** Accessors ************************/
    const math::AABB&   GetAABB() const;
    
    void                SetTree( QuadTree* _pTree );
    QuadTree*           GetTree() const;
    void                SetNode( QuadTreeNode* _pNode );
    QuadTreeNode*       GetNode() const;

    virtual void        SetCenter( float _fX, float _fY );
    virtual void        Move( float _fX, float _fY );
    
protected:
    ////////////////////////////////////////////////////////////
    /// Compute the AABB
    /// TODO Angle not taken into account, compute AABB when rotating ?
    ///
    ////////////////////////////////////////////////////////////
    virtual void        ComputeAABB() = 0;

    /******************* Protected members ********************/
    QuadTree*           m_pTree;    /// Tree we are in
    QuadTreeNode*       m_pNode;    /// Node we are in
    math::AABB          m_AABB;     /// Axis Aligned Bounding Box

#ifdef _DEBUG
public:
    virtual void        DebugRender( const sf::Color& _Color = sf::Color::White ) const;
#endif // _DEBUG
};

/************************** Inline ************************/
inline const math::AABB& QuadTreeOccupant::GetAABB() const {
    return m_AABB;
}
    
inline void QuadTreeOccupant::SetTree( QuadTree* _pTree ) {
    m_pTree = _pTree;
}

inline QuadTree* QuadTreeOccupant::GetTree() const {
    return m_pTree;
}

inline void QuadTreeOccupant::SetNode( QuadTreeNode* _pNode ) {
    m_pNode = _pNode;
}

inline QuadTreeNode* QuadTreeOccupant::GetNode() const {
    return m_pNode;
}

    } // namespace smeg::light
} // namespace smeg

#include <SmegTools/Debug/DebugNewOff.hpp>

#endif // QUAD_TREE_OCCUPANT_HPP
